package com.hunau.iot.server.nettyserver;

import com.hunau.iot.server.common.excention.AuthFailExcetion;
import com.hunau.iot.server.common.inboundhandler.MySimpleChannelInboundHandler;
import com.hunau.iot.server.common.persist.BaseMo;
import com.hunau.iot.server.common.persist.spi.ServiceSupport;
import com.hunau.iot.server.utils.SpringContextUtils;
import com.hunau.system.domain.TbIoterminal;
import com.hunau.system.service.impl.TbIoterminalServiceImpl;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @program: ruoyi
 * @description: 终端登陆鉴权，第一次的环境数据相当于告诉服务器它的imei号
 * 环境数据案例：aa,12,02,1066293093741388,27.90,55.80,0.16,0,0.00,0.00,1009,0.00,正西,无雨雪,0,0,0CC
 * 能源数据案例，在第一次连接时发送的第一条数据为该数据时，不做处理：AA,12,01,22.51,0.00,0.00,0.00,22.26,22.28,0.02,0.02,01,255,CC
 * @author: Mr.Liu
 * @create: 2020-03-21 17:23
 **/
public class AuthHandler extends SimpleChannelInboundHandler<String> {
    private static final Logger logger = LoggerFactory.getLogger(AuthHandler.class);
    private static BaseMo baseMo;
    static {
        try{
            baseMo = ServiceSupport.load(BaseMo.class);
        }catch (Exception e){

        }
    }
    /**
     * 更新数据库状态
     * @param MiME
     * @param status
     */
    private void updateTbIot(String MiME , Integer status,String addr){
        TbIoterminal tbIoterminal = new TbIoterminal();
        tbIoterminal.setImei(MiME);
        tbIoterminal.setConip(addr);
        tbIoterminal.setOnline(String.valueOf(status));
        baseMo.update(tbIoterminal);
    }
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String o) throws Exception {
        String[] list = o.split(",");
        if(list.length<4){
            throw new AuthFailExcetion("鉴权：数据包格式错误");
        }
        if(!"AA".equals(list[0]) && !"aa".equals(list[0])){

            throw new AuthFailExcetion("鉴权：数据包包头错误");
        }
        if(!"12".equals(list[1])){
            throw new AuthFailExcetion("鉴权：数据包数据类型错误");
        }
        if("02".equals(list[2])){
            //MIME                       //password
            if(!"".equals(list[3])){
                //这个不要它自动释放，不然后面的接收不到数据了
                ctx.pipeline().addBefore("heart","CheckH",new CheckHandler(true));
                //参数true表示最后释放掉byteBuf
                ctx.pipeline().addBefore("heart","ConnectH",new ConnectHandler(new AtomicInteger(2),false));

                //保存通道
                ChannelManage.dev1Mime.put(list[3],ctx.channel());
                ChannelManage.dev2id.put(ctx.channel().id().toString(),list[3]);
                //更新数据库状态
                updateTbIot(list[3],1,ctx.channel().remoteAddress().toString().substring(1));
                //移除当前handler
                ctx.pipeline().remove(this.getClass());
                ctx.fireChannelRead(o);
            }else {
                throw new AuthFailExcetion("数据无效");
            }
        }
    }

    /**
     * 本handler中的异常拦截
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if(cause instanceof AuthFailExcetion){
            logger.error(ctx.channel().id()+">>>发来的登陆数据错误：\""+cause.getMessage()+"\"，关闭连接"+">>>"+HeartBeatServer.dataTime());
        }
        System.out.println(cause);
        //应该发送响应码给客户端
        ctx.writeAndFlush(Unpooled.copiedBuffer("600".getBytes()));
        ctx.close();
    }
}
